package one;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class grammarAnalysis {
    public static String[] keys = {
            "const", "int", "char", "void", "main",
            "if", "else", "do", "while", "for", "scanf", "printf", "return",
            "+", "-", "*", "/", "<", "<=", ">", ">=", "==", "!=", "=", ";", ",", "(", ")", "[", "]", "{", "}"
    };
    public static String[] values = {
            "CONSTTK", "INTTK", "CHARTK", "VOIDTK", "MAINTK",
            "IFTK", "ELSETK", "DOTK", "WHILETK", "FORTK", "SCANFTK", "PRINTFTK", "RETURNTK",
            "PLUS", "MINU", "MULT", "DIV", "LSS", "LEQ", "GRE", "GEQ", "EQL", "NEQ", "ASSIGN", "SEMICN", "COMMA", "LPARENT", "RPARENT", "LBRACK", "RBRACK", "LBRACE", "RBRACE"
    };
    public static String[] custom = {
            "IDENFR", "INTCON", "CHARCON", "STRCON"
    };
    public static String[] code = {
            "001", "002", "003", "004", "005"
    };

    public static String[] tWords;

    public static String[] kWords;

    public static int i;

    public static String nowWord;

    public static StringBuffer output = new StringBuffer();

    public static List<String> functionHaveReturn = new ArrayList<>();

    public static List<String> functionNoReturn = new ArrayList<>();

    /**
     * 读取文件内容为字符串
     * @param file 文件对象
     * @return 返回文件内容字符串
     * @throws IOException
     */
    public static String getFile(File file) throws IOException {
        StringBuffer sb = new StringBuffer();
        BufferedReader br = new BufferedReader(new FileReader(file));
        String data = br.readLine();
        while(data != null){
            sb.append(data + "\n");
            data = br.readLine();
        }
        br.close();
        String files = "";
        for (int i = 0; i < sb.length(); i++) {
            char ch = sb.charAt(i);
            if(ch == '\n'){
                continue;
            }
            if(ch == ' ' && i > 0 && (sb.charAt(i - 1) == ' ' || sb.charAt(i - 1) == '\n')){
                continue;
            }
            files += ch;
        }
        files = files.trim();
        return files;
    }

    /**
     * 判断字符是否为字母
     * @param ch 输入字符
     * @return 输出boolean类型
     */
    public static boolean isLetter(char ch){
        return (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || ch == '_';
    }

    /**
     * 判断字符是否为数字
     * @param ch 输入字符
     * @return 输出boolean类型
     */
    public static boolean isDigit(char ch){
        return ch >= '0' && ch <= '9';
    }

    /**
     * 从左到右根据词法进行检测，分类标识
     * @param chs 输入字符数组
     * @return 返回分词数组和标识数组
     */
    public static List<List<String>> classify(char[] chs){
        List<List<String>> lists = new ArrayList<>();
        List<String> listKey = new ArrayList<>();
        List<String> listValue = new ArrayList<>();
        int i = 0;
        String word = "";
        char head = 0;
        do {
            char ch = chs[i];
            if (word.length() == 0) {
                head = ch;
            }
            i++;
            if (isLetter(ch)) {
                word += ch;
            } else if (isDigit(ch)) {
                word += ch;
            } else {
                if (isLetter(head)) {
                    listKey.add(word);
                    listValue.add("001");
                } else if (isDigit(head)) {
                    listKey.add(word);
                    listValue.add("002");
                }
                word = "";
                head = 0;
                if (ch != ' ') {
                    if(ch != '\'' && ch != '\"'){
                        if((ch == '!' || ch == '=' || ch == '>' || ch == '<') && chs[i] == '='){
                            word = word + ch + chs[i++];
                        }else{
                            word += ch;
                        }
                        listKey.add(word);
                        listValue.add("003");
                    }else if(ch == '\''){
                        listKey.add(String.valueOf(chs[i++]));
                        listValue.add("004");
                        i++;
                    }else{
                        while(chs[i] != '\"'){
                            word += chs[i++];
                        }
                        listKey.add(word);
                        listValue.add("005");
                        i++;
                    }
                    word = "";
                }
            }
        } while (i != chs.length);
        lists.add(listKey);
        lists.add(listValue);
        return lists;
    }

    /**
     * 获取每个词对应的类别码
     * @param listKey 词列表
     * @param listValue 类型列表
     * @return 返回单词对应token字列表
     * @throws IOException
     */
    public static List<String> getToken(List<String> listKey, List<String> listValue) throws IOException {
        Map<String, String> map = new HashMap<>();
        List<String> token = new ArrayList<>();
        for (int i = 0; i < keys.length; i++) {
            map.put(keys[i], values[i]);
        }
        for (int i = 0; i < listKey.size(); i++) {
            String key = listKey.get(i);
            String value = listValue.get(i);
            if(value.equals(code[0]) || value.equals(code[2])){
                boolean isExist = map.containsKey(key);
                if(isExist){
                    token.add(map.get(key));
                }else{
                    token.add(custom[0]);
                }
            }else if(value.equals(code[1])){
                token.add(custom[1]);
            }else if(value.equals(code[3])){
                token.add(custom[2]);
            }else if(value.equals(code[4])){
                token.add(custom[3]);
            }
        }
        return token;
    }

    /**
     * 程序
     */
    public static void program(){
        nowWord = tWords[i++];
        constEx();
        varEx();
        while (tWords[i+1].equals("LPARENT")){
            if(nowWord.equals("INTTK") || nowWord.equals("CHARTK")){
                unVoidFunction();
            }else if(nowWord.equals("VOIDTK")){
                if(!tWords[i].equals("MAINTK")){
                    voidFunction();
                }else{
                    mainFunction();
                    break;
                }
            }
        }
        output.append("<程序>\n");
    }

    /**
     * 常量说明
     */
    public static void constEx(){
        int temp = i;
        while(nowWord.equals("CONSTTK")){
            output.append(nowWord).append(" ").append(kWords[i-1]).append("\n");
            nowWord = tWords[i++];
            constDe();
            if(nowWord.equals("SEMICN")){
                output.append(nowWord).append(" ").append(kWords[i-1]).append("\n");
                nowWord = tWords[i++];
            }
        }
        if(temp != i){
            output.append("<常量说明>\n");
        }
    }

    /**
     * 常量定义
     */
    public static void constDe(){
        if(nowWord.equals("INTTK")){
            output.append(nowWord).append(" ").append(kWords[i-1]).append("\n");
            nowWord = tWords[i++];
            idenfr();
            if(nowWord.equals("ASSIGN")){
                output.append(nowWord).append(" ").append(kWords[i-1]).append("\n");
                nowWord = tWords[i++];
                integer();
            }
            while (nowWord.equals("COMMA")) {
                output.append(nowWord).append(" ").append(kWords[i-1]).append("\n");
                nowWord = tWords[i++];
                idenfr();
                if(nowWord.equals("ASSIGN")){
                    output.append(nowWord).append(" ").append(kWords[i-1]).append("\n");
                    nowWord = tWords[i++];
                    integer();
                }
            }
        }else if(nowWord.equals("CHARTK")){
            output.append(nowWord).append(" ").append(kWords[i-1]).append("\n");
            nowWord = tWords[i++];
            idenfr();
            if(nowWord.equals("ASSIGN")){
                output.append(nowWord).append(" ").append(kWords[i-1]).append("\n");
                nowWord = tWords[i++];
                character();
            }
            while (nowWord.equals("COMMA")) {
                output.append(nowWord).append(" ").append(kWords[i-1]).append("\n");
                nowWord = tWords[i++];
                idenfr();
                if(nowWord.equals("ASSIGN")){
                    output.append(nowWord).append(" ").append(kWords[i-1]).append("\n");
                    nowWord = tWords[i++];
                    character();
                }
            }
        }
        output.append("<常量定义>\n");
    }

    /**
     * 标识符
     */
    public static void idenfr(){
        if(nowWord.equals("IDENFR")){
            output.append(nowWord).append(" ").append(kWords[i-1]).append("\n");
            nowWord = tWords[i++];
        }
    }

    /**
     * 整数
     */
    public static void integer(){
        int temp = i;
        if(nowWord.equals("PLUS") || nowWord.equals("MINU")){
            output.append(nowWord).append(" ").append(kWords[i-1]).append("\n");
            nowWord = tWords[i++];
        }
        unsignedInteger();
        if(temp != i){
            output.append("<整数>\n");
        }
    }

    /**
     * 无符号整数
     */
    public static void unsignedInteger(){
        if(nowWord.equals("INTCON")){
            output.append(nowWord).append(" ").append(kWords[i-1]).append("\n");
            nowWord = tWords[i++];
            output.append("<无符号整数>\n");
        }
    }

    /**
     * 字符
     */
    public static void character(){
        if(nowWord.equals("CHARCON")){
            output.append(nowWord).append(" ").append(kWords[i-1]).append("\n");
            nowWord = tWords[i++];
        }
    }

    /**
     * 变量说明
     */
    public static void varEx(){
        int temp = i;
        while(tWords[i+1].equals("COMMA") || tWords[i+1].equals("ASSIGN") || tWords[i+1].equals("SEMICN") || tWords[i+1].equals("LBRACK")){
            varDe();
            if(nowWord.equals("SEMICN")){
                output.append(nowWord).append(" ").append(kWords[i-1]).append("\n");
                nowWord = tWords[i++];
            }
        }
        if(temp != i){
            output.append("<变量说明>\n");
        }
    }

    /**
     * 变量定义
     */
    public static void varDe(){
        if (nowWord.equals("INTTK") || nowWord.equals("CHARTK")){
            output.append(nowWord).append(" ").append(kWords[i-1]).append("\n");
            nowWord = tWords[i++];
            idenfr();
            if(nowWord.equals("LBRACK")){
                output.append(nowWord).append(" ").append(kWords[i-1]).append("\n");
                nowWord = tWords[i++];
                unsignedInteger();
                if(nowWord.equals("RBRACK")){
                    output.append(nowWord).append(" ").append(kWords[i-1]).append("\n");
                    nowWord = tWords[i++];
                }
            }
            while(nowWord.equals("COMMA")){
                output.append(nowWord).append(" ").append(kWords[i-1]).append("\n");
                nowWord = tWords[i++];
                idenfr();
                if(nowWord.equals("LBRACK")){
                    output.append(nowWord).append(" ").append(kWords[i-1]).append("\n");
                    nowWord = tWords[i++];
                    unsignedInteger();
                    if(nowWord.equals("RBRACK")){
                        output.append(nowWord).append(" ").append(kWords[i-1]).append("\n");
                        nowWord = tWords[i++];
                    }
                }
            }
            output.append("<变量定义>\n");
        }
    }

    /**
     * 有返回值函数
     */
    public static void unVoidFunction(){
        declarationHeader();
        if(nowWord.equals("LPARENT")){
            output.append(nowWord).append(" ").append(kWords[i-1]).append("\n");
            nowWord = tWords[i++];
            parametersTable();
            output.append(nowWord).append(" ").append(kWords[i-1]).append("\n");
            nowWord = tWords[i++];
        }
        if(nowWord.equals("LBRACE")){
            output.append(nowWord).append(" ").append(kWords[i-1]).append("\n");
            nowWord = tWords[i++];
            compoundStatement();
            output.append(nowWord).append(" ").append(kWords[i-1]).append("\n");
            nowWord = tWords[i++];
        }
        output.append("<有返回值函数定义>\n");
    }

    /**
     * 无返回值函数
     */
    public static void voidFunction(){
        functionNoReturn.add(kWords[i]);
        if(nowWord.equals("VOIDTK")){
            output.append(nowWord).append(" ").append(kWords[i-1]).append("\n");
            nowWord = tWords[i++];
            idenfr();
            if(nowWord.equals("LPARENT")){
                output.append(nowWord).append(" ").append(kWords[i-1]).append("\n");
                nowWord = tWords[i++];
                parametersTable();
                output.append(nowWord).append(" ").append(kWords[i-1]).append("\n");
                nowWord = tWords[i++];
            }
            if(nowWord.equals("LBRACE")){
                output.append(nowWord).append(" ").append(kWords[i-1]).append("\n");
                nowWord = tWords[i++];
                compoundStatement();
                output.append(nowWord).append(" ").append(kWords[i-1]).append("\n");
                nowWord = tWords[i++];
            }
        }
        output.append("<无返回值函数定义>\n");
    }

    /**
     * 主函数
     */
    public static void mainFunction(){
        if(nowWord.equals("VOIDTK")){
            output.append(nowWord).append(" ").append(kWords[i-1]).append("\n");
            nowWord = tWords[i++];
            if(nowWord.equals("MAINTK")){
                output.append(nowWord).append(" ").append(kWords[i-1]).append("\n");
                nowWord = tWords[i++];
                if(nowWord.equals("LPARENT")){
                    output.append(nowWord).append(" ").append(kWords[i-1]).append("\n");
                    nowWord = tWords[i++];
                    output.append(nowWord).append(" ").append(kWords[i-1]).append("\n");
                    nowWord = tWords[i++];
                    if(nowWord.equals("LBRACE")){
                        output.append(nowWord).append(" ").append(kWords[i-1]).append("\n");
                        nowWord = tWords[i++];
                        compoundStatement();
                        output.append(nowWord).append(" ").append(kWords[i-1]).append("\n");
                    }
                }
            }
        }
        output.append("<主函数>\n");
    }

    /**
     * 头部声明
     */
    public static void declarationHeader(){
        output.append(nowWord).append(" ").append(kWords[i-1]).append("\n");
        nowWord = tWords[i++];
        functionHaveReturn.add(kWords[i-1]);
        idenfr();
        output.append("<声明头部>\n");
    }

    /**
     * 参数表
     */
    public static void parametersTable(){
        if(!nowWord.equals("RPARENT")){
            output.append(nowWord).append(" ").append(kWords[i-1]).append("\n");
            nowWord = tWords[i++];
            idenfr();
            while(nowWord.equals("COMMA")){
                output.append(nowWord).append(" ").append(kWords[i-1]).append("\n");
                nowWord = tWords[i++];
                output.append(nowWord).append(" ").append(kWords[i-1]).append("\n");
                nowWord = tWords[i++];
                idenfr();
            }
        }
        output.append("<参数表>\n");
    }

    /**
     * 复合语句
     */
    public static void compoundStatement(){
        if(nowWord.equals("CONSTTK")){
            constEx();
        }
        if(nowWord.equals("INTTK") || nowWord.equals("CHARTK")){
            varEx();
        }
        statementColumn();
        output.append("<复合语句>\n");
    }

    /**
     * 语句列
     */
    public static void statementColumn(){
        do {
            statement();
        }while (!nowWord.equals("RBRACE"));
        output.append("<语句列>\n");
    }

    /**
     * 语句
     */
    public static void statement(){
        int temp = i;
        conditionalStatements();
        loopStatement();
        if(nowWord.equals("LBRACE")){
            output.append(nowWord).append(" ").append(kWords[i-1]).append("\n");
            nowWord = tWords[i++];
            statementColumn();
            output.append(nowWord).append(" ").append(kWords[i-1]).append("\n");
            nowWord = tWords[i++];
        }
        if(temp == i){
            if(functionHaveReturn.contains(kWords[i-1])){
                callFunctionHaveReturn();
            }else if(functionNoReturn.contains(kWords[i-1])){
                callFunctionNoReturn();
            }else if(nowWord.equals("IDENFR")){
                assignment();
            }else if(nowWord.equals("SCANFTK")){
                read();
            }else if(nowWord.equals("PRINTFTK")){
                write();
            }else if(nowWord.equals("RETURNTK")){
                returnStatement();
            }
            if(nowWord.equals("SEMICN")){
                output.append(nowWord).append(" ").append(kWords[i-1]).append("\n");
                nowWord = tWords[i++];
            }
        }
        if(temp != i){
            output.append("<语句>\n");
        }
    }

    /**
     * 条件语句
     */
    public static void conditionalStatements(){
        if(nowWord.equals("IFTK")){
            output.append(nowWord).append(" ").append(kWords[i-1]).append("\n");
            nowWord = tWords[i++];
            if(nowWord.equals("LPARENT")){
                output.append(nowWord).append(" ").append(kWords[i-1]).append("\n");
                nowWord = tWords[i++];
                conditional();
                output.append(nowWord).append(" ").append(kWords[i-1]).append("\n");
                nowWord = tWords[i++];
                statement();
                if(nowWord.equals("ELSETK")){
                    output.append(nowWord).append(" ").append(kWords[i-1]).append("\n");
                    nowWord = tWords[i++];
                    statement();
                }
            }
            output.append("<条件语句>\n");
        }
    }

    /**
     * 条件
     */
    public static void conditional(){
        expression();
        int temp = i;
        relationalOperator();
        if(temp != i){
            expression();
        }
        output.append("<条件>\n");
    }

    /**
     * 表达式
     */
    public static void expression(){
        int temp = i;
        if(nowWord.equals("PLUS") || nowWord.equals("MINU")){
            output.append(nowWord).append(" ").append(kWords[i-1]).append("\n");
            nowWord = tWords[i++];
        }
        item();
        while(nowWord.equals("PLUS") || nowWord.equals("MINU")){
            output.append(nowWord).append(" ").append(kWords[i-1]).append("\n");
            nowWord = tWords[i++];
            item();
        }
        if(temp != i) output.append("<表达式>\n");
    }

    /**
     * 关系运算符
     */
    public static void relationalOperator(){
        if(nowWord.equals("LSS") || nowWord.equals("LEQ") || nowWord.equals("GRE") || nowWord.equals("GEQ") || nowWord.equals("EQL") || nowWord.equals("NEQ")){
            output.append(nowWord).append(" ").append(kWords[i-1]).append("\n");
            nowWord = tWords[i++];
        }
    }

    /**
     * 项
     */
    public static void item(){
        int temp = i;
        factor();
        while(nowWord.equals("MULT") || nowWord.equals("DIV")){
            output.append(nowWord).append(" ").append(kWords[i-1]).append("\n");
            nowWord = tWords[i++];
            factor();
        }
        if(temp != i){
            output.append("<项>\n");
        }
    }

    /**
     * 因子
     */
    public static void factor(){
        int temp = i;
        if(nowWord.equals("IDENFR")){
            if(tWords[i].equals("LPARENT")){
                callFunctionHaveReturn();
            }else{
                output.append(nowWord).append(" ").append(kWords[i-1]).append("\n");
                nowWord = tWords[i++];
                if(nowWord.equals("LBRACK")){
                    output.append(nowWord).append(" ").append(kWords[i-1]).append("\n");
                    nowWord = tWords[i++];
                    expression();
                    output.append(nowWord).append(" ").append(kWords[i-1]).append("\n");
                    nowWord = tWords[i++];
                }
            }
        }else if(nowWord.equals("LPARENT")){
            output.append(nowWord).append(" ").append(kWords[i-1]).append("\n");
            nowWord = tWords[i++];
            expression();
            output.append(nowWord).append(" ").append(kWords[i-1]).append("\n");
            nowWord = tWords[i++];
        }else{
            integer();
            character();
        }
        if(temp != i){
            output.append("<因子>\n");
        }
    }

    /**
     * 循环语句
     */
    public static void loopStatement(){
        int temp = i;
        if(nowWord.equals("WHILETK")){
            output.append(nowWord).append(" ").append(kWords[i-1]).append("\n");
            nowWord = tWords[i++];
            if (nowWord.equals("LPARENT")) {
                output.append(nowWord).append(" ").append(kWords[i-1]).append("\n");
                nowWord = tWords[i++];
                conditional();
                output.append(nowWord).append(" ").append(kWords[i-1]).append("\n");
                nowWord = tWords[i++];
            }
            statement();
        }else if(nowWord.equals("DOTK")){
            output.append(nowWord).append(" ").append(kWords[i-1]).append("\n");
            nowWord = tWords[i++];
            statement();
            output.append(nowWord).append(" ").append(kWords[i-1]).append("\n");
            nowWord = tWords[i++];
            if (nowWord.equals("LPARENT")) {
                output.append(nowWord).append(" ").append(kWords[i-1]).append("\n");
                nowWord = tWords[i++];
                conditional();
                output.append(nowWord).append(" ").append(kWords[i-1]).append("\n");
                nowWord = tWords[i++];
            }
        }else if(nowWord.equals("FORTK")){
            output.append(nowWord).append(" ").append(kWords[i-1]).append("\n");
            nowWord = tWords[i++];
            if (nowWord.equals("LPARENT")) {
                output.append(nowWord).append(" ").append(kWords[i-1]).append("\n");
                nowWord = tWords[i++];
                idenfr();
                if (nowWord.equals("ASSIGN")) {
                    output.append(nowWord).append(" ").append(kWords[i-1]).append("\n");
                    nowWord = tWords[i++];
                    expression();
                    if (nowWord.equals("SEMICN")) {
                        output.append(nowWord).append(" ").append(kWords[i-1]).append("\n");
                        nowWord = tWords[i++];
                    }
                }
                conditional();
                if (nowWord.equals("SEMICN")) {
                    output.append(nowWord).append(" ").append(kWords[i-1]).append("\n");
                    nowWord = tWords[i++];
                }
                idenfr();
                if (nowWord.equals("ASSIGN")) {
                    output.append(nowWord).append(" ").append(kWords[i-1]).append("\n");
                    nowWord = tWords[i++];
                    idenfr();
                    if (nowWord.equals("PLUS") || nowWord.equals("MINU")) {
                        output.append(nowWord).append(" ").append(kWords[i-1]).append("\n");
                        nowWord = tWords[i++];
                        stepSize();
                    }
                }
                output.append(nowWord).append(" ").append(kWords[i-1]).append("\n");
                nowWord = tWords[i++];
                statement();
            }
        }
        if(temp != i){
            output.append("<循环语句>\n");
        }
    }

    /**
     * 步长
     */
    public static void stepSize(){
        int temp = i;
        unsignedInteger();
        if(temp != i){
            output.append("<步长>\n");
        }
    }

    /**
     * 赋值语句
     */
    public static void assignment(){
        idenfr();
        output.append(nowWord).append(" ").append(kWords[i-1]).append("\n");
        nowWord = tWords[i++];
        expression();
        if(nowWord.equals("RBRACK")){
            output.append(nowWord).append(" ").append(kWords[i-1]).append("\n");
            nowWord = tWords[i++];
            if(nowWord.equals("ASSIGN")){
                output.append(nowWord).append(" ").append(kWords[i-1]).append("\n");
                nowWord = tWords[i++];
                expression();
            }
        }
        output.append("<赋值语句>\n");
    }

    /**
     * 读语句
     */
    public static void read(){
        output.append(nowWord).append(" ").append(kWords[i-1]).append("\n");
        nowWord = tWords[i++];
        if(nowWord.equals("LPARENT")){
            output.append(nowWord).append(" ").append(kWords[i-1]).append("\n");
            nowWord = tWords[i++];
            idenfr();
            while(nowWord.equals("COMMA")){
                output.append(nowWord).append(" ").append(kWords[i-1]).append("\n");
                nowWord = tWords[i++];
                idenfr();
            }
            output.append(nowWord).append(" ").append(kWords[i-1]).append("\n");
            nowWord = tWords[i++];
        }
        output.append("<读语句>\n");
    }

    /**
     * 写语句
     */
    public static void write(){
        output.append(nowWord).append(" ").append(kWords[i-1]).append("\n");
        nowWord = tWords[i++];
        if(nowWord.equals("LPARENT")){
            output.append(nowWord).append(" ").append(kWords[i-1]).append("\n");
            nowWord = tWords[i++];
            if(nowWord.equals("STRCON")){
                output.append(nowWord).append(" ").append(kWords[i-1]).append("\n");
                nowWord = tWords[i++];
                output.append("<字符串>\n");
                if(nowWord.equals("COMMA")){
                    output.append(nowWord).append(" ").append(kWords[i-1]).append("\n");
                    nowWord = tWords[i++];
                    expression();
                }
            } else {
                expression();
            }
            output.append(nowWord).append(" ").append(kWords[i-1]).append("\n");
            nowWord = tWords[i++];
        }
        output.append("<写语句>\n");
    }

    /**
     * 返回语句
     */
    public static void returnStatement(){
        output.append(nowWord).append(" ").append(kWords[i-1]).append("\n");
        nowWord = tWords[i++];
        if(nowWord.equals("LPARENT")){
            output.append(nowWord).append(" ").append(kWords[i-1]).append("\n");
            nowWord = tWords[i++];
            expression();
            output.append(nowWord).append(" ").append(kWords[i-1]).append("\n");
            nowWord = tWords[i++];
        }
        output.append("<返回语句>\n");
    }

    /**
     * 有返回值的函数调用
     */
    public static void callFunctionHaveReturn(){
        idenfr();
        if(nowWord.equals("LPARENT")){
            output.append(nowWord).append(" ").append(kWords[i-1]).append("\n");
            nowWord = tWords[i++];
            valueParameterTable();
            output.append(nowWord).append(" ").append(kWords[i-1]).append("\n");
            nowWord = tWords[i++];
        }
        output.append("<有返回值函数调用语句>\n");
    }

    /**
     * 无返回值的函数调用
     */
    public static void callFunctionNoReturn(){
        idenfr();
        if(nowWord.equals("LPARENT")){
            output.append(nowWord).append(" ").append(kWords[i-1]).append("\n");
            nowWord = tWords[i++];
            valueParameterTable();
            output.append(nowWord).append(" ").append(kWords[i-1]).append("\n");
            nowWord = tWords[i++];
        }
        output.append("<无返回值函数调用语句>\n");
    }

    /**
     * 值参数表
     */
    public static void valueParameterTable(){
        expression();
        while (nowWord.equals("COMMA")){
            output.append(nowWord).append(" ").append(kWords[i-1]).append("\n");
            nowWord = tWords[i++];
            expression();
        }
        output.append("<值参数表>\n");
    }

    public static void writeResult() throws IOException {
        OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("output.txt"), StandardCharsets.UTF_8);
        osw.write(output.toString());
        osw.close();
    }

    public static void main(String[] args) throws IOException {
        File file = new File("testfile.txt");
        String str = getFile(file);
        char[] chs = str.toCharArray();
        List<List<String>> lists = classify(chs);
        List<String> listKey = lists.get(0);
        List<String> listValue = lists.get(1);
        List<String> token = getToken(listKey, listValue);
        tWords = new String[listKey.size()];
        kWords = new String[listKey.size()];
        for (int j = 0; j < tWords.length; j++) {
            tWords[j] = token.get(j);
            kWords[j] = listKey.get(j);
        }
        i = 0;
        program();
        writeResult();
    }
}
